
#include<iostream>
#include<string>
#include<regex>


int main()
{
    //HTTP请求行格式
    //GET /baidu/tieba/login?user=xioaming&passwd=123456 HTTP/1.1\r\n
    std::string str = "GET /baidu/tieba/login?user=xioaming&passwd=123456 HTTP/1.1";
    std::smatch matchs;
    //请求方法的匹配！GET HEAD POST PUT DELETE
    std::regex e("(GET|HEAD|POST|PUT|DELETE) ([^?]*)\\?(.*) (HTTP/1\\.[01])");
    //[^?]非问号字符！[^?]*表示一次或者多次的非问号字符
    //第一个括号是获得方法，第二个括号是获取资源路径！
    //第三个括号是为了T恤查询字符串！
    //\\?表示一个原始问号字符！ ——\?在字符串里面被转义了，得再加个一个问号表示原始问号！
    //.在正则表达式有特殊含义！要进行转义！
    //这样子就获取了HTTP的版本！
    bool ret = std::regex_match(str,matchs,e);

    if (ret == false)
    {
        std::cout << "failed!" << std::endl;
        return -1;
    }

    for (auto &s : matchs)
    {
        std::cout << s << std::endl;
    }


    std::string str1 = "GET /baidu/tieba/login?user=xioaming&passwd=123456 HTTP/1.1\r\n";//如果后面有\r\n要如何匹配呢？

    std::smatch matchs1;
    //这时候按照上面的就匹配不出来了！
    std::regex e1("(GET|HEAD|POST|PUT|DELETE) ([^?]*)\\?(.*) (HTTP/1\\.[01])(?:\n|\r\n)?");
    //(?:.....)表示匹配某个格式的字符串！但是不捕抓！但是要加上括号！
    //(....?)最后的括号表示前面的表达式出现了一次或者0次！


    bool ret1 = std::regex_match(str1,matchs1,e1);

    if (ret1 == false)
    {
        std::cout << "failed!" << std::endl;
        return -1;
    }

    for (auto &s : matchs1)
    {
        std::cout << s << std::endl;
    }


    std::string str1 = "GET /baidu/tieba/login HTTP/1.1\r\n";//如果后面有\r\n要如何匹配呢？
    std::regex e2("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*)?) (HTTP/1\\.[01])(?:\n|\r\n)?");
    //(?:\\?(.*)?)这个表示以问号开始的字符串我们不捕抓它！我们捕抓的是问号后面的字符串！
    //然后这个字符串可以出现一次或者0次！

    return 0;
}